﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Caching.Distributed;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Newtonsoft.Json;
using RedLockNet.SERedis;
using StackExchange.Redis;
using Tsual.Wechat;
using Tsual.Wechat.Cache;
using Tsual.Wechat.Filters;
using Tsual.Wechat.Formatters;
using Tsual.Wechat.Message;
using Tsual.Wechat.Message.Impl;
using Tsual.Wechat.Pipes;
using wechat_service.Controllers;
using Tsual.DataPipeline;

namespace wechat_service
{
    public class Startup
    {
        public Startup(IConfiguration configuration, ILogger<Startup> logger, ILoggerFactory loggerFactory)
        {
            Configuration = configuration;
            this.logger = logger;
            this.loggerFactory = loggerFactory;
        }

        public ILogger<Startup> logger;
        public IConfiguration Configuration { get; }
        public ILoggerFactory loggerFactory { get; }
        public IHostingEnvironment env { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            //services.AddStackExchangeRedisCache(option =>
            //{
            //    option.Configuration = Configuration["Redis"];
            //});
            services.AddSingleRedisCache(ConfigurationOptions.Parse(Configuration["Redis"])).AddRedLock();
            services.AddDbContext<AppDbContext>();
            services.AddIdentity<AppIdentityUser, IdentityRole>()
                .AddEntityFrameworkStores<AppDbContext>()
                .AddDefaultTokenProviders();

            services.AddTsualDataPipeline(cfg => { })
                .ConfigureMould<PmouldWechatCore>(customSetter: (mould, pip, sp) => {
                    mould.KnownUsers.AddPipe<DbpipeKonwnUser>();
                })
                .ConfigureMould<PmouldWechatTemplate>();

            services.AddTsualWechat(cfg =>
            {
                cfg.AppId = Configuration["Wechat:AppId"];
                cfg.AppSecret = Configuration["Wechat:AppSecret"];
                cfg.Token = Configuration["Wechat:Token"];
                cfg.CacheHead = "CASTNETCORE";
                cfg.AesEncryptKey = Configuration["Wechat:EncodingAesKey"];
                cfg.ControllerRoute = "wechat";
            });//.AddHostedService<RefreshUserHostedService>();
            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2)
                .AddDefaultWechatController();
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env, IDatabase cache, ILogger<Startup> logger, IApplicationLifetime applicationLifetime, AppDbContext db, IHttpClientFactory httpClientFactory,RedLockFactory lockFactory,PmouldWechatCore wechatCore)
        {
            db.Database.EnsureCreated();
            applicationLifetime.ApplicationStarted.Register(async () =>
            {
                logger.LogDebug("微信ACCESS_TOKEN初始化，值{0}", await WechatContext.Instance.GetAccessTokenAsync(env.IsDevelopment()));
            });
    //        var tl = wechatCore.UserAccessToken.WriteAsync(JsonConvert.DeserializeObject<WsrmUserAccessToken>(new StreamReader(File.OpenRead("test.json")).ReadToEnd()), new DpmmUserAccessToken("061eAUva1UQZQN1nIita1lRMva1eAUv6", null))
    //.GetAwaiter().GetResult();
    //        tl.WriteResultToJsonFile("aut1.json");
    //        var tq = wechatCore.UserAccessToken.ReadAsync(new DpmmUserAccessToken("061eAUva1UQZQN1nIita1lRMva1eAUv6", null))
    //            .GetAwaiter().GetResult();
    //        tq.WriteResultToJsonFile("aut2.json");

            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler("/Home/Error");
                // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
                app.UseHsts();
            }




            //app.UseHttpsRedirection();
            app.UseStaticFiles();
            app.UseCookiePolicy();

            app.UseMvc(routes =>
            {
                routes.MapRoute(
                    name: "default",
                    template: "{controller=Home}/{action=Index}/{id?}");
            });
        }
    }
}
